/*
* coder: Dzlua
* email: 505544956@qq.com
* time : 2018-05-17 09:17
*/
#pragma once
#ifndef __MEMORY_HPP__
#define __MEMORY_HPP__

#include <memory>
#include <vector>
#include <map>

UI_BEGIN_NAMESPACE

/*
* Warning: 
* You must be guaranteed that it cannot go beyond the scope.
*/
template <typename T>
class CSimpleArray {
public:
    CSimpleArray() = default;
public:
    typedef T TELE_INFO;
    typedef std::vector<TELE_INFO> TMAP_INFO;
    typedef typename TMAP_INFO::const_iterator TMAP_ITOR;
    typedef typename TMAP_INFO::iterator TMAP_CONST_ITOR;
public:
    // add a element at the end.
    void add(TELE_INFO &ele) { map_.push_back(ele); }
    // add a element at idx.
    void insert(TELE_INFO &ele, size_t idx) { map_.insert(map_.begin() + idx, ele); }
    void insert(TELE_INFO &ele, TMAP_CONST_ITOR itor) { map_.insert(itor, ele); }
    // erase idx
    void erase(size_t idx) { map_.erase(map_.begin() + idx); }
    // the count of all elements.
    auto size() { return map_.size(); }
    // if map_ is empty.
    bool empty() { return map_.empty(); }
    // clear all elements.
    void clear() { map_.clear(); }
    // return the first element.
    auto front() { return map_.front(); }
    // return the last element.
    auto back() { return map_.back(); }
    // return the element at idx. 
    auto at(size_t idx) { return map_.at(idx); }
    // the first iterator.
    auto begin() { return map_.begin(); }
    // the last iterator.
    auto end() { return map_.end(); }
    // the rfirst iterator.
    auto rbegin() { return map_.rbegin(); }
    // the rlast iterator.
    auto rend() { return map_.rend(); }
protected:
    TMAP_INFO map_;
};

template <typename T>
class CArray {
public:
    CArray() = default;
public:
    typedef T TELE_INFO;
    typedef std::vector<TELE_INFO> TMAP_INFO;
    typedef typename TMAP_INFO::const_iterator TMAP_ITOR;
    typedef typename TMAP_INFO::iterator TMAP_CONST_ITOR;
public:
    // add a element at the end.
    void add(TELE_INFO &ele) { map_.push_back(ele); }
    // add a element at idx.
    void insert(TELE_INFO &ele, size_t idx) { map_.insert(map_.begin() + idx, ele); }
    void insert(TELE_INFO &ele, TMAP_CONST_ITOR itor) { map_.insert(itor, ele); }
    // erase idx
    void erase(size_t idx) { map_.erase(map_.begin() + idx); }
    // erase iterator.
    void erase(TMAP_CONST_ITOR itor) { map_.erase(itor); }
    // the count of all elements.
    auto size() { return map_.size(); }
    // if map_ is empty.
    bool empty() { return map_.empty(); }
    // clear all elements.
    void clear() { map_.clear(); }
    // return the first element.
    auto front() { return map_.front(); }
    // return the last element.
    auto back() { return map_.back(); }
    // return the element at idx. 
    auto at(size_t idx) { return map_.at(idx); }
    // the first iterator.
    auto begin() { return map_.begin(); }
    // the last iterator.
    auto end() { return map_.end(); }
    // the rfirst iterator.
    auto rbegin() { return map_.rbegin(); }
    // the rlast iterator.
    auto rend() { return map_.rend(); }
public:
    // erase element.
    void erase(TELE_INFO &ele) { 
        for (auto itor = map_.begin(); itor != map_.end(); ++itor) {
            if ((*itor) == ele) {
                map_.erase(itor);
                return;
            }
        }
    }
    // the idx of element.
    bool index(const TELE_INFO &ele, size_t *idx) {
        if (!idx) return false;
        TMAP_ITOR itor;
        bool ret = iterator(ele, &itor);
        if (ret) {
            *idx = itor - map_.begin();
        }
        return ret;
    }
    // the iterator of element.
    bool iterator(const TELE_INFO &ele, TMAP_ITOR *itor) {
        if (!itor) return false;
        for (auto it = map_.begin(); it != map_.end(); ++it) {
            if ((*it) == ele) {
                *itor = it;
                return true;
            }
        }
        return false;
    }
protected:
    TMAP_INFO map_;
};

template <typename T, typename V>
class CSimpleMap {
public:
    CSimpleMap() = default;
public:
    typedef V TELE_INFO;
    typedef std::map<T, TELE_INFO> TMAP_INFO;
    typedef typename TMAP_INFO::const_iterator TMAP_ITOR;
    typedef typename TMAP_INFO::iterator TMAP_CONST_ITOR;
public:
    // add a element.
    void insert(const T &key, TELE_INFO &ele) { map_.insert(std::pair<T, TELE_INFO>(key, ele)); }
    // get the element of key
    auto at(const T &key) { return map_.at(key); }
    // get the iterator of the key.
    auto find(const T &key) { return map_.find(key); }
    // erase by key.
    void erase(const T &key) { map_.erase(key); }
    // erase by iterator.
    void erase(TMAP_CONST_ITOR itor) { map_.erase(itor); }
    // return the size of map.
    auto size() { return map_.size(); }
    // if map is empty.
    bool empty() { return map_.empty(); }
    // empty the map.
    void clear() { map_.clear(); }
    // the first iterator.
    auto begin() { return map_.begin(); }
    // the last iterator.
    auto end() { return map_.end(); }
    // the rfirst iterator.
    auto rbegin() { return map_.rbegin(); }
    // the rlast iterator.
    auto rend() { return map_.rend(); }
protected:
    TMAP_INFO map_;
};

template <typename T, typename V>
class CMap {
public:
    CMap() = default;
public:
    typedef V TELE_INFO;
    typedef std::map<T, TELE_INFO> TMAP_INFO;
    typedef typename TMAP_INFO::const_iterator TMAP_ITOR;
    typedef typename TMAP_INFO::iterator TMAP_CONST_ITOR;
public:
    // add a element.
    void insert(const T &key, TELE_INFO &ele) { map_.insert(std::pair<T, TELE_INFO>(key, ele)); }
    // get the element of key
    auto at(const T &key) { return map_.at(key); }
    // get the iterator of the key.
    auto find(const T &key) { return map_.find(key); }
    // erase by key.
    void erase(const T &key) { map_.erase(key); }
    // erase by iterator.
    void erase(TMAP_CONST_ITOR itor) { map_.erase(itor); }
    // return the size of map.
    auto size() { return map_.size(); }
    // if map is empty.
    bool empty() { return map_.empty(); }
    // empty the map.
    void clear() { map_.clear(); }
    // the first iterator.
    auto begin() { return map_.begin(); }
    // the last iterator.
    auto end() { return map_.end(); }
    // the rfirst iterator.
    auto rbegin() { return map_.rbegin(); }
    // the rlast iterator.
    auto rend() { return map_.rend(); }
public:
    // get the iterator of the element.
    auto find(TELE_INFO &ele) {
        for (auto itor = map_.begin(); itor != map_.end(); ++itor) {
            if (itor->second == ele) {
                return itor;
            }
        }
        return map_.end();
    }
    // erase by element.
    void erase(TELE_INFO &ele) {
        for (auto itor = map_.begin(); itor != map_.end(); ++itor) {
            if (itor->second == ele) {
                map_.erase(itor);
                return;
            }
        }
    }
protected:
    TMAP_INFO map_;
};

UI_END_NAMESPACE

#endif